//
// Created by Administrator on 2017/9/24.
//
#include <jni.h>
#include <string>
#include <malloc.h>
#include <android/log.h>
#include <android/bitmap.h>
#include "gif_lib.h"
#define  LOG_TAG    "david"
#define  argb(a,r,g,b) ( ((a) & 0xff) << 24 ) | ( ((b) & 0xff) << 16 ) | ( ((g) & 0xff) << 8 ) | ((r) & 0xff)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

typedef struct GifBean{
    //    播放当前帧数
    int currentFrame;
//    下一帧的播放时长  数组
    int *dealys;

    int totalFrame;
}GifBean;
//绘制图像
void drawFrame(GifFileType *gifFileType, GifBean *gifBean, AndroidBitmapInfo info, void *pixels) {
//        拿到当前 帧
    SavedImage savedImage = gifFileType->SavedImages[gifBean->currentFrame];
    GifImageDesc frameInfo=savedImage.ImageDesc;
    //    某一个像素位置
    int pointPixel;
    GifByteType gifByteType;
    GifColorType gifColorType;
    ColorMapObject* colorMapObject=frameInfo.ColorMap;
    int *px = (int *) pixels;
//    位的运算
    px = (int *)((char *)px + info.stride * frameInfo.Top);
    int *line;
    for (int y = frameInfo.Top; y <frameInfo.Top+frameInfo.Height ; ++y) {
        line = px;
        for (int x = frameInfo.Left; x < frameInfo.Left + frameInfo.Width; ++x) {
            pointPixel = (y - frameInfo.Top) * frameInfo.Width + (x - frameInfo.Left);
            //但是不能直接用   被压缩  int
            gifByteType=savedImage.RasterBits[pointPixel];
            gifColorType=colorMapObject->Colors[gifByteType];
            line[x]=argb(255,gifColorType.Red,gifColorType.Green,gifColorType.Blue);
//        一行的像素
            px = (int *)((char*)px + info.stride);
        }
    }
}

extern "C"{
    JNIEXPORT jlong JNICALL
    Java_com_dbgs_gifdnndklib_GifHandler_loadGif(JNIEnv *env, jobject instance, jstring Path_) {
        const char *path = env->GetStringUTFChars( Path_, 0);
        int erro;
        GifFileType * gifFileType= DGifOpenFileName(path,&erro);
//    初始化结构体的变量
        DGifSlurp(gifFileType);
        GifBean *gifBean = (GifBean *) malloc(sizeof(GifBean));
        memset(gifBean, 0, sizeof(GifBean));
        gifFileType->UserData = gifBean;
        gifBean->dealys = (int *)malloc(sizeof(int) * gifFileType->ImageCount);
        memset(gifBean->dealys, 0, sizeof(int) * gifFileType->ImageCount);
        // TODO
        //    播放时长赋值
        ExtensionBlock *extensionBlock;
        for (int i = 0; i < gifFileType->ImageCount; ++i) {
            SavedImage frame = gifFileType->SavedImages[i];
            for (int j = 0; j < frame.ExtensionBlockCount; ++j) {
                if (GRAPHICS_EXT_FUNC_CODE == frame.ExtensionBlocks[j].Function){
                    //图形控制扩展块
                    extensionBlock = &frame.ExtensionBlocks[j];
                    break;
                }
            }
            if(extensionBlock){
                //第三个字节  5	延迟时间	第二个字节   6	延迟时间	D
               // 第三个字节  5	延迟时间	第二个字节   6	延迟时间	D
                int fra_delay = 10*((extensionBlock->Bytes[2] << 8) | extensionBlock->Bytes[1]);
                gifBean->dealys[i] = fra_delay;
            }
        }
        gifBean->totalFrame = gifFileType->ImageCount;
        env->ReleaseStringUTFChars( Path_, path);
    }

    JNIEXPORT jint JNICALL
    Java_com_dbgs_gifdnndklib_GifHandler_getWidth__J(JNIEnv *env, jobject instance, jlong gifPoint) {

        // TODO
        GifFileType *gifFileType = (GifFileType *) gifPoint;
        return  gifFileType->SWidth;
    }

    JNIEXPORT jint JNICALL
    Java_com_dbgs_gifdnndklib_GifHandler_getHeight__J(JNIEnv *env, jobject instance, jlong gifPoint) {
        // TODO
        GifFileType *gifFileType = (GifFileType *) gifPoint;
        return gifFileType->SHeight;
    }

    JNIEXPORT jint JNICALL
    Java_com_dbgs_gifdnndklib_GifHandler_updateFrame__Landroid_graphics_Bitmap_2J(JNIEnv *env,
                                                                                  jobject instance,
                                                                                  jobject bitmap,
                                                                                  jlong gifPoint) {

        // TODO
        GifFileType *gifFileType= (GifFileType *) gifPoint;
        GifBean *gifBean = (GifBean *) gifFileType->UserData;
        AndroidBitmapInfo info;
        AndroidBitmap_getInfo(env, bitmap, &info);
        //    byte*
        void *pixels;
//    锁定画布   一副bitmap
        AndroidBitmap_lockPixels(env, bitmap, &pixels);
        //绘制图形
        drawFrame(gifFileType, gifBean, info, pixels);
        //   控制当前播放量
        gifBean->currentFrame += 1;
//    播放到最后一帧
        LOGE("当前帧  %d  ",gifBean->currentFrame);
        if (gifBean->currentFrame >= gifBean->totalFrame - 1) {
            gifBean->currentFrame = 0;
            LOGE("重新过来  %d  ",gifBean->currentFrame);
        }
        AndroidBitmap_unlockPixels(env, bitmap);
        return gifBean->dealys[gifBean->currentFrame];
    }

};
